﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ComputerGraphics.Geometry
{
    public class Point3D
    {
        private double x;
        private double y;
        private double z;

        public static Point3D operator +(Point3D a, Point3D b)
        {
            return new Point3D(a.x + b.x, a.y + b.y, a.z + b.z);
        }

        public static Point3D operator -(Point3D a, Point3D b)
        {
            return new Point3D(a.x - b.x, a.y - b.y, a.z - b.z);
        }

        public static Point3D operator *(Point3D a, double scale)
        {
            return new Point3D(a.x * scale, a.y * scale, a.z * scale);
        }

        public static Point3D operator *(double scale, Point3D a)
        {
            return a * scale;
        }

        public static double operator *(Point3D a, Point3D b)
        {
            return a.x * b.x + a.y * b.y + a.z * b.z;
        }

        public static Point3D operator ^(Point3D a, Point3D b)
        {
            return new Point3D(-a.z * b.y + a.y * b.z, a.z * b.x - a.x * b.z, - a.y * b.x + a.x * b.y);
        }

        public static Point3D operator -(Point3D a)
        {
            return new Point3D(-a.x, -a.y, -a.z);
        }

        public static Point3D operator /(Point3D a, double scale)
        {
            return new Point3D(a.x / scale, a.y / scale, a.z / scale);
        }

        public Point3D(double x, double y, double z)
        {
            this.x = x;
            this.y = y;
            this.z = z;
        }

        public double X
        {
            get { return x; }
        }

        public double Y
        {
            get { return y; }
        }

        public double Z
        {
            get { return z; }
        }

        public double Norm
        {
            get { return Math.Sqrt(this.SquareNorm); }
        }

        public Point3D Direction
        {
            get { return this / this.Norm; }
        }

        public double SquareNorm
        {
            get { return x * x + y * y + z * z; }
        }
    }
}
